Skip to content

Add single-file market maker bot example#15

Draft
WGB5445 wants to merge 12 commits intomainfrom
logan/market-maker-bot-example
Draft

Add single-file market maker bot example#15
WGB5445 wants to merge 12 commits intomainfrom
logan/market-maker-bot-example

Conversation

@WGB5445
Copy link
Copy Markdown
Collaborator

@WGB5445 WGB5445 commented Apr 14, 2026

Summary

Add a new single-file market maker bot example under examples/write/market_maker_bot.py.

What is included

  • Inventory-skew quote computation around mid price
  • Basic risk guards (max_inventory, max_margin_usage)
  • Cancel-and-replace quoting cycle
  • Dry-run mode for safe validation
  • CLI flags for market, network, timing, and risk parameters

Why

This keeps the market-maker example self-contained and easy to run with the current Python SDK API surface.

Validation

  • Script compiles and --help runs successfully
  • Formatting and lint adjustments were applied on this branch

Copilot AI review requested due to automatic review settings April 14, 2026 07:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a self-contained, single-file example market maker bot script to demonstrate basic cancel/replace quoting with inventory skew and risk guards using the current Decibel Python SDK APIs.

Changes:

  • Introduces examples/write/market_maker_bot.py implementing a periodic quoting loop (fetch state → cancel existing orders → place post-only bid/ask).
  • Adds CLI/env configuration for market/network/timing and basic risk limits (inventory and margin usage).
  • Implements quote rounding to market tick/lot sizes via SDK utilities.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write/market_maker_bot.py
Comment thread examples/write/market_maker_bot.py Outdated
Comment thread examples/write/market_maker_bot.py
@WGB5445
Copy link
Copy Markdown
Collaborator Author

WGB5445 commented Apr 14, 2026

Addressed all three review points in commit d52a4f4:

  1. Dry-run cancel path
  • _cancel_market_orders now accepts write: DecibelWriteDex | None.
  • _run_cycle now executes cancel handling when (settings.dry_run or write is not None) and open_order_ids, so dry-run can simulate cancel logs.
  1. Distinguishable quote outcomes
  • Added QuoteStatus and QuoteDecision.
  • _compute_quotes now returns explicit statuses (OK, PAUSE_NO_PRICE, PAUSE_INVENTORY_LIMIT, PAUSE_SIZE_INVALID) instead of overloading None.
  • _run_cycle branches by status, avoiding misleading inventory-limit messages for size/config issues.
  1. Fatal handling for configuration errors
  • Main loop now treats ValueError as fatal config errors, prints fatal config error: ..., and exits with non-zero status (2).

Also added focused tests in tests/test_market_maker_bot.py for:

  • dry-run cancel simulation without write client
  • quote status behavior for size-invalid and inventory-limit cases
  • spread-too-tight ValueError
  • fatal exit path on config ValueError

Validation run locally:

  • ruff check (targeted files)
  • ruff format --check
  • pytest tests/test_market_maker_bot.py tests/abi/test_registry.py

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write/market_maker_bot.py Outdated
Comment thread examples/write/market_maker_bot.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write/market_maker_bot.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write/market_maker_bot.py Outdated
Comment thread examples/write/market_maker_bot.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write/market_maker_bot.py Outdated
Comment thread examples/write/market_maker_bot.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write/market_maker_bot.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write/market_maker_bot.py Outdated
Comment thread examples/write/market_maker_bot.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@WGB5445 WGB5445 requested a review from gregnazario April 14, 2026 10:53
gregnazario
gregnazario previously approved these changes Apr 14, 2026
Copy link
Copy Markdown
Collaborator

@gregnazario gregnazario left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine, let's add documentation (saying what it does, since it is an example)

Document the market maker bot example with features, usage instructions, and configuration options. The bot demonstrates building a trading bot with inventory skew, margin management, and dry-run mode support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write/market_maker_bot.py Outdated
Comment thread examples/write/market_maker_bot.py
Comment thread examples/write/market_maker_bot.py
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread examples/write/market_maker_bot.py Outdated
Comment on lines +463 to +468
parser.add_argument("--spread", type=float, default=os.getenv("MM_SPREAD", "0.001"))
parser.add_argument(
"--order-size",
type=float,
default=os.getenv("MM_ORDER_SIZE", "0.001"),
)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Numeric argparse options are using environment-variable strings as default values (e.g., default=os.getenv("MM_SPREAD", "0.001") with type=float). argparse does not apply the type converter to defaults, so these end up as str when the flag is omitted, and invalid env values (like MM_SPREAD=abc) won't trigger an argparse error (the included test expects a SystemExit(2)). Parse env vars into float/int before passing them as defaults (and call parser.error(...) on parse failure), and apply the same fix to all other numeric args here (order size, max inventory, skew, refresh/cooldown, cancel-resync, max-cycles).

Copilot uses AI. Check for mistakes.
Comment thread README.md Outdated
Comment on lines +173 to +174
# Live mode (requires PRIVATE_KEY)
export PRIVATE_KEY="0x..."
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README uses different PRIVATE_KEY formats: earlier it says your_private_key_hex, but this new section shows export PRIVATE_KEY="0x...". Please make the format consistent (or explicitly note that the 0x prefix is optional/accepted) to avoid copy/paste failures when calling PrivateKey.from_hex(...).

Suggested change
# Live mode (requires PRIVATE_KEY)
export PRIVATE_KEY="0x..."
# Live mode (requires PRIVATE_KEY as a hex string; use the same format consistently.
# If your setup uses PrivateKey.from_hex(...), omit the 0x prefix unless your parser explicitly accepts it.)
export PRIVATE_KEY="your_private_key_hex"

Copilot uses AI. Check for mistakes.
@WGB5445 WGB5445 requested a review from Copilot April 18, 2026 10:51
@WGB5445 WGB5445 marked this pull request as draft April 18, 2026 10:51
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +533 to +538
if not math.isfinite(settings.max_inventory) or settings.max_inventory <= 0:
raise ValueError("max_inventory must be a finite value > 0; adjust --max-inventory")
if not math.isfinite(settings.max_margin_usage) or settings.max_margin_usage <= 0:
raise ValueError("max_margin_usage must be a finite value > 0; adjust --max-margin-usage")


Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_validate_settings() currently only checks max_inventory and max_margin_usage, but other user-controlled settings (e.g., spread, order_size, skew_per_unit, and the timing fields) can also be non-finite/negative and will only fail later inside _compute_quotes() or asyncio.sleep(). Consider validating all numeric settings up-front here (and producing a single actionable error) so the script fails fast before entering the cycle loop.

Suggested change
if not math.isfinite(settings.max_inventory) or settings.max_inventory <= 0:
raise ValueError("max_inventory must be a finite value > 0; adjust --max-inventory")
if not math.isfinite(settings.max_margin_usage) or settings.max_margin_usage <= 0:
raise ValueError("max_margin_usage must be a finite value > 0; adjust --max-margin-usage")
errors: list[str] = []
finite_positive_fields = (
("spread", settings.spread, "--spread"),
("order_size", settings.order_size, "--order-size"),
("max_inventory", settings.max_inventory, "--max-inventory"),
("skew_per_unit", settings.skew_per_unit, "--skew-per-unit"),
("max_margin_usage", settings.max_margin_usage, "--max-margin-usage"),
("refresh_interval_s", settings.refresh_interval_s, "--refresh-interval"),
("cooldown_s", settings.cooldown_s, "--cooldown"),
("cancel_resync_s", settings.cancel_resync_s, "--cancel-resync"),
)
for field_name, value, flag in finite_positive_fields:
if not math.isfinite(value) or value <= 0:
errors.append(f"{field_name} must be a finite value > 0; adjust {flag}")
if settings.max_cycles < 0:
errors.append("max_cycles must be >= 0 (0 = run forever); adjust --max-cycles")
if errors:
raise ValueError("Invalid market maker settings: " + "; ".join(errors))

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants